﻿﻿﻿﻿﻿using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Factories;
using DeviceCommons.DeviceMessages.Models.V1;
using DeviceCommons.Validation;

namespace DeviceCommons.DeviceMessages.Builders
{
    public class DeviceInfoReadingBuilder
    {
        private readonly DeviceMessageInfoReading _reading;
        private readonly List<IDeviceMessageInfoReadingState> _states = new();
        private readonly byte _deviceType;

        public DeviceInfoReadingBuilder(DeviceMessageInfoReading reading, byte deviceType)
        {
            _reading = reading;
            _deviceType = deviceType;
        }

        public DeviceInfoReadingBuilder AddState(byte sid, object value, StateValueTypeEnum? valueType = null)
        {
            // 前置验证
            DeviceMessageValidator.ValidateStateId(sid);
            
            // 推断值类型（如果未提供）
            var actualValueType = valueType ?? InferValueType(value);
            DeviceMessageValidator.ValidateStateValue(value, actualValueType);
            DeviceMessageValidator.ValidateEnum(actualValueType, nameof(valueType));
            
            // 验证状态数量限制
            DeviceMessageValidator.ValidateStateCount(_states.Count + 1);

            var factory = StateFactoryRegistry.GetFactory(_deviceType);
            var state = factory.CreateState(sid, value, actualValueType);
            _states.Add(state);
            return this;
        }

        /// <summary>
        /// 推断值类型
        /// </summary>
        /// <param name="value">值</param>
        /// <returns>推断的值类型</returns>
        private static StateValueTypeEnum InferValueType(object value)
        {
            return value switch
            {
                string => StateValueTypeEnum.String,
                byte[] => StateValueTypeEnum.Binary,
                int => StateValueTypeEnum.Int32,
                short => StateValueTypeEnum.Int16,
                ushort => StateValueTypeEnum.UInt16,
                float => StateValueTypeEnum.Float32,
                double => StateValueTypeEnum.Double,
                bool => StateValueTypeEnum.Bool,
                ulong => StateValueTypeEnum.Timestamp,
                _ => throw new DeviceMessageValidationException(
                    ValidationErrorType.ValueTypeConversionFailed,
                    $"不支持的值类型，无法推断 StateValueTypeEnum: {value.GetType().Name}",
                    nameof(value),
                    "可支持的类型: string, byte[], int, short, ushort, float, double, bool, ulong",
                    value.GetType().Name)
            };
        }

        public DeviceMessageInfoReading Build()
        {
            _reading.State = new DeviceMessageInfoReadingStates
            {
                StateArray = [.. _states]
            };
            return _reading;
        }
    }
}
